home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk15 / qrt / docs / tech.doc < prev    next >
Text File  |  1995-03-18  |  20KB  |  529 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.         
  8.         
  9.                              QRT Technical Reference
  10.         
  11.         
  12.         INTRODUCTION
  13.         
  14.         The QRT ray tracing system  has  been  designed  to make the code
  15.         easily maintainable and  expandable.   An  object oriented design
  16.         philosophy was used for the  program,  and the resulting code has
  17.         been made as robust as practical given time constraints.
  18.         
  19.         This document explains the design of QRT.  First, the function of
  20.         each QRT C file will be listed.    Next,  the QRT data structures
  21.         will  be  explained,   and   finally,   some   details   of  code
  22.         implementation discussed.
  23.         
  24.         
  25.         QRT C CODE FILES
  26.         
  27.         The QRT code is broken down  into  16 C files and 3 header files,
  28.         each containing a group of related  functions.  The files are, in
  29.         alphabetical order:
  30.         
  31.            FILE              FUNCTION                              
  32.         
  33.            bbox.c            bounding box intersection routines
  34.            error.c           error reporting routines
  35.            inout.c           recursive decent input parser
  36.            instance.c        file for INSTANCE primitives
  37.            intersect.c       object intersection routines
  38.            lexer.c           simple lexical analyzer
  39.            mth.c             vector math support
  40.            norm.c            normal finding functions for objects
  41.            offset.c          offsets a primitive by dx, dy, dz
  42.            pattern.c         finds pattern info for objects
  43.            patternio.c       auxiliary parser for patterns
  44.            precomp.c         pre-computes some info for objects
  45.            qrt.c             main routine and initialization code
  46.            ray.c             actual ray tracing algorithims
  47.            relpos.c          finds relative position on an object
  48.            resize.c          resize any primitive
  49.            stack.c           stack and object creation routines
  50.         
  51.            header.h          instantiations of some global variables
  52.            pattern.h         pattern info
  53.            qrt.h             data structure definitions
  54.         
  55.         
  56.         The function of each  group  of  routines  will  be  discussed in
  57.         greater detail in rest of this document.
  58.  
  59.  
  60.         QRT Ray Tracer               Page 1           Technical Reference
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.  
  71.  
  72.  
  73.         
  74.         DATA STRUCTURES
  75.         
  76.         All QRT data  structures  are  defined  in  qrt.h.   This file is
  77.         broken down into sections, as follows:
  78.         
  79.          OBJECT TYPE DEFINITIONS:
  80.            C #define  statements  for  each  object  type  (sphere, lamp,
  81.            observer, etc).
  82.            
  83.          MISC DEFINES
  84.            Other #defines for screen size, etc.
  85.            
  86.          VECTOR data structure
  87.            A floating point 3-tuple vector definition.
  88.            
  89.          COLOR VECTOR data structure
  90.            A red,green,blue integer 3-tuple structure.
  91.            
  92.          COLOR INFO structure
  93.            This is an important structure. It lists color information for
  94.            an    object,    including    ambient    and   diffuse   light
  95.            characteristics,  reflection   and  transmission  data,  Phong
  96.            specular  reflection  coefficient,  index  of  refraction, and
  97.            object dithering data.
  98.            
  99.          PRECOMPUTE structure
  100.            This contains some fields which can be filled with precomputed
  101.            information before the  ray-tracing  is begun. This saves time
  102.            by eliminating redundant  calculations  for  every line/object
  103.            intersection.   The  use   of   these  fields  is  up  to  the
  104.            intersection routines.  Each  object  also  has a 'precompute'
  105.            routine which fills this structure.
  106.            
  107.          PATTERN structure
  108.            The  pattern  definition   structure  contains  a  color  info
  109.            structure.  It is used  to  change  the  characteristics  of a
  110.            primitive  object  over  the  surface  of  that  object.   For
  111.            example, checkered, brick, or tile patterns may be defined.
  112.            
  113.          OBJECT structure
  114.            The base structure of  QRT.   All  objects  are  defined as an
  115.            object structure.  This structure contains:
  116.            
  117.               A) A location vector for the object
  118.               B) 3 directional vectors
  119.               C) The object type flag
  120.               D) Some constants for QUADRATIC objects
  121.               E) A color info structure
  122.               F) Sibling and child pointers for the object tree
  123.               G) A pointer to a pattern structure
  124.  
  125.  
  126.         QRT Ray Tracer               Page 2           Technical Reference
  127.  
  128.  
  129.  
  130.  
  131.  
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.               H) x and y multipliers for pattern sizing
  140.               I) A name field for the object
  141.            
  142.          WORLD structure
  143.            This structure contains all data about the world.  It contains
  144.            pointers to the object tree, the  lamp list, the observer, and
  145.            the sky, and the pattern  stack.   It  also contains statistic
  146.            information, such as  total  number  of  rays  traced, and the
  147.            output file name and pointer.
  148.            
  149.          OBJECT_DATA structure
  150.            The header.h file contains  an  array  of  this structure, one
  151.            array element per object type.   The structure itself contains
  152.            pointers to functions that perform  known operations on object
  153.            structures.  This design  allows  much cleaner code and easier
  154.            addition of object types.  The object function pointers are:
  155.            
  156.               ColTest:  Tests for object collisions
  157.            
  158.               FindNorm: Finds normal to surface at a given position
  159.            
  160.               FindBbox: Computes size of bounding box for object
  161.            
  162.               RelPos:   Finds relative position on object surface
  163.                         given a position in space
  164.            
  165.               PreComp:  Stuffs 'precomp' structure for each object
  166.                         before ray-tracing is begun.  The precomp and
  167.                         intersect routines must agree on the exact usage
  168.                         of the fields in this structure.
  169.            
  170.               Offset:   Moves a primitive by dx, dy, dz.  This is used
  171.                         for instances.
  172.            
  173.               Resize:   Resizes a primitive ( and scales its location
  174.                         vector).  This is also used for instances.
  175.            
  176.            This structure permits expressions such as:
  177.            
  178.               (*(ObjData[CurrObj->type].ColTest))(line,Currobj,&t);
  179.            
  180.            which means:
  181.            
  182.               (collision func for this obj type )(parameters);
  183.            
  184.            instead of a large case  statement.   Execution is faster, and
  185.            if new  objects  are  added,  the  code  does  not  have to be
  186.            changed.  If a  certain  operation  is  illegal  for a certain
  187.            object type, the ObjData  entry  points  to an Err() function.
  188.            This way, if something  goes  wrong,  execution  is terminated
  189.            gracefully instead of jumping to a random location in memory.
  190.  
  191.  
  192.         QRT Ray Tracer               Page 3           Technical Reference
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204.  
  205.            
  206.          MATH defines
  207.            MIN, MAX, SQRT, DotProd macros
  208.            
  209.          DEFAULT structure
  210.            Keeps default color information
  211.            
  212.          ERROR codes
  213.            Defines for all possible error conditions
  214.            
  215.          ROBUST flag
  216.            There are many sections of code of the form:
  217.            
  218.               # ifdef ROBUST
  219.                  code
  220.               # endif
  221.            
  222.            such that, if ROBUST is defined, the bounds-checking code will
  223.            be compiled.  It is recommended  that this flag be always set,
  224.            although SLIGHTLY faster execution is possible with it reset.
  225.            
  226.            
  227.         CODE DESCRIPTION
  228.         
  229.         The function of each section of  code  will  be described in more
  230.         detail here.
  231.         
  232.          BBOX.C
  233.            
  234.            Contains code for each  object  type  that  will determine the
  235.            size of the bounding box for that  object.  Bounding boxes are
  236.            logical objects that contain other objects.  If a ray does not
  237.            strike a bounding box, it  cannot  possibly  strike any object
  238.            inside the box.  This  can  increase  execution  speed if used
  239.            correctly.
  240.            
  241.            Routines in BBOX.C are of the form:
  242.            
  243.              BboxSphere(v1,v2,obj)
  244.                VECT_PTR v1,v2;
  245.                OBJ_PTR obj;
  246.            
  247.            where v1 and  v2  are  vectors  for  the  two  corners  of the
  248.            bounding box, and obj is a pointer to an object.
  249.            
  250.            The functions  are  called  based  upon  their  pointer in the
  251.            ObjData structure.
  252.            
  253.          ERROR.C
  254.          
  255.            This is a simple file that  contains  just  two routines.  The
  256.  
  257.  
  258.         QRT Ray Tracer               Page 4           Technical Reference
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.  
  271.            first one is the Err() routine that  fills empty places in the
  272.            ObjData structure.   The  second  routine  is the actual error
  273.            reporting routine.  It takes  two  arguments: an error number,
  274.            and an error code.   The  error  number  is  a #define such as
  275.            'SYNTAX_ERROR'  or  'INTERNAL_ERROR'.   The  error  code is an
  276.            integer used to find the routine  in which the error occurred.
  277.            The error code  number  is  arbitrary  but  should  be  unique
  278.            throughout the program.  A convention has been set up that all
  279.            routines within one C file return  an error code with the same
  280.            first digit (501, 502,  503...).   If the error occurred while
  281.            parsing the input file, the offending  line number is printed.
  282.            Execution is always terminated after calling this routine.
  283.            
  284.          INOUT.C
  285.            
  286.            This is a recursive decent parser  for the input language. The
  287.            parser was hand coded, since  YACC  or a similar compiler tool
  288.            was  not  available.   The   input   routines  perform  syntax
  289.            checking, and some bounds checking.   The bounds checking will
  290.            catch some errors; however,  its  has  not been idiot-proofed.
  291.            It is up to the user to not  make  strange  entries (radius=0,
  292.            etc). Most of these  illogical  errors  will  be caught in the
  293.            run-time bounds checking.
  294.            
  295.            INOUT has one routine for  each  non-terminal  in the grammar.
  296.            The routine accepts parameters,  in any order, and branches to
  297.            another routine, or  inputs  a  value.   This  is  the largest
  298.            individual file, at over 1000 lines.
  299.            
  300.          INSTANCE.C
  301.            
  302.            This contains the  routines  to  input  instance  definitions,
  303.            create a copy of a sub-tree, offset the subtree, and scale the
  304.            subtree.
  305.            
  306.          INTERSECT.C
  307.            
  308.            This   file   contains   routines   to   perform   line/object
  309.            intersection tests.  Each routine is of the form:
  310.            
  311.              int LineSphere(line, sphere, t)
  312.                    OBJ_PTR line, sphere;
  313.                    float *t;
  314.            
  315.            where line and sphere are inputs, and t is an output.  Line is
  316.            always a line  object,  but  the  second  parameter  may  be a
  317.            pointer  a  different  object  for  a  different  intersection
  318.            routine.   The routine must  compute  the  parameter T for the
  319.            intersection point on the line, if any, and return TRUE if the
  320.            line hits the object, or FALSE if it does not.
  321.            
  322.  
  323.  
  324.         QRT Ray Tracer               Page 5           Technical Reference
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.            The functions  are  called  based  upon  their  pointer in the
  338.            ObjData structure.
  339.            
  340.          LEXER.C
  341.            
  342.            This is a simple tokenizer  for  the  input language.  In this
  343.            implementation, #include directives for the input language are
  344.            not implemented, but they belong  in this routine. This module
  345.            also contains some  bounds  checking  code,   and  code to map
  346.            values  of   the   range   0..1   to   0..CNUM.    The   light
  347.            characteristics are stored as  an  integer from 0 to CNUM, but
  348.            the input values are a  floating  point  value from 0 to 1, so
  349.            these routines perform the conversion.
  350.            
  351.          MTH.C
  352.            
  353.            MTH contains support routines for  vector math, such as vector
  354.            addition, subtraction, and cross product.
  355.            
  356.          NORM.C
  357.            
  358.            These routines find the normal vector  to an object at a given
  359.            location in space.  They are called  based upon the pointer in
  360.            the ObjData structure.  A typical entry is:
  361.            
  362.               SphereNorm(norm, object, position)
  363.                 VECT_PTR norm, position;
  364.                 OBJ_PTR object;
  365.            
  366.            where object and position are input, and norm is output.
  367.            
  368.            Often, several objects share  one  routine.  This happens, for
  369.            example,  with  planar  objects,  since  the  code to find the
  370.            normal to a plane is the same  regardless  of the shape of the
  371.            planar object.
  372.            
  373.          OFFSET.C
  374.            
  375.            These routines are called by  the  object_data  structure. One
  376.            routine  exists  per  primitive  type,  and  they  offset  the
  377.            primitive by the given amount.
  378.            
  379.          PATTERN.C
  380.            
  381.            When a ray/object intersection is  found, the pattern function
  382.            is called.  If  the  objects  pattern  pointer  is  NULL,  the
  383.            default color info for that object  is returned.  If it is not
  384.            NULL, the the relative position  on the surface of that object
  385.            is found, and the color info for  the pattern at that location
  386.            is returned.   If  the  relative  location  is  not inside any
  387.            sub-pattern, then the object's default color info is returned.
  388.  
  389.  
  390.         QRT Ray Tracer               Page 6           Technical Reference
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.            
  404.            To determine if  a  given  point  is  inside  a sub-pattern, a
  405.            similar strategy to the object intersection  routines is used.
  406.            There are several sub-pattern types  (RECTANGLE, CIRCLE, etc),
  407.            and there is a table  listing  pointers  to  containment  test
  408.            routines for each type.  This makes it easy to add sub-pattern
  409.            types.
  410.            
  411.          PATTERNIO.C
  412.            
  413.            An auxiliary parser for  patterns,  created  because INOUT was
  414.            getting  too  large  to  comfortably  edit.   This  file  also
  415.            contains routines to copy  subtrees,  as well as to offset and
  416.            scale subtrees by calling routines from offset.c and resize.c
  417.            
  418.          PRECOMP.C
  419.            
  420.            Contains  routines  to  stuff   the  'precomp'  structure  for
  421.            objects.  See the  documentation  for  the qrt.h file for more
  422.            details.   This  structure   saves   time  by  computing  some
  423.            expressions  that  do  not   change   with   each  line/object
  424.            intersection test.
  425.            
  426.          QRT.C
  427.            
  428.            This module contains initialization code, and the main routine
  429.            that loads the 'world'  and  performs  the  ray tracing. It is
  430.            quite short.
  431.            
  432.          RAY.C
  433.            
  434.            All of the ray tracing  logic  is  in  this module.  The basic
  435.            routine  is  Ray_Trace.   Ray_Trace  looks  for  a  ray/object
  436.            intersection.  If it  finds  one,  various  color routines are
  437.            called to compute the color of the  object at this point. Some
  438.            of these color routines may  call  Ray_Trace  recursively (for
  439.            reflection or transmission).
  440.            
  441.            Another important routine,  called  by  Ray_Trace, is Ray_Hit.
  442.            This actually tests  to  see  if  the  ray  hits  an object by
  443.            walking through the object tree.   If the 'first' flag is set,
  444.            the routine will quit after it  finds  one object intersection
  445.            (used to see if a surface is in the shadow of another object).
  446.            Otherwise, all intersections are sorted in order of increasing
  447.            parameter T, and the first such intersection returned.
  448.            
  449.          RELPOS.C
  450.            
  451.            Routines in RELPOS  are  called  by  the  entry in the ObjData
  452.            array.  A typical routine is:
  453.            
  454.  
  455.  
  456.         QRT Ray Tracer               Page 7           Technical Reference
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.  
  466.  
  467.  
  468.  
  469.            
  470.                SpherePos(obj,loc,pos1,pos2)
  471.                  OBJ_PTR  obj;
  472.                  VECT_PTR loc;
  473.                  float *pos1, *pos2;
  474.            
  475.            
  476.            where obj and loc are input, and  the routine must compute the
  477.            coordinates pos1 and pos2 on  the  surface of the object. This
  478.            is used to map patterns onto the surface of arbitrary objects.
  479.            It  is  straightforward   for   planar  surfaces.   For  other
  480.            surfaces, a mapping of the form:
  481.            
  482.                3-tuple(x,y,z) --> 2-tuple(x,y)
  483.            
  484.            must be created for the object.
  485.            
  486.          RESIZE.C
  487.            
  488.            These routines resize objects, and  scale the location vector.
  489.            One  routine  per  object.   They  are  used  by  the instance
  490.            routines (as are routines from offset.c).
  491.            
  492.          STACK.C
  493.            
  494.            This file  contains  support  code  for  object  tree and list
  495.            manipulations.  The name "STACK"  is partially historical; the
  496.            initial implementation of the program did not permit arbitrary
  497.            object trees,  only  linear  lists.   STACK  also  contains an
  498.            object  creation  routine,   and  a  routine  to  print  world
  499.            statistics at the end of the ray tracing session.
  500.            
  501.            Note that  in  the  files  that  contain  object  manipulation
  502.            routines (indexed by the  object_data  structure array), there
  503.            is often a common routine for  several  similar  objects.  For
  504.            example, all planar objects  (PARALLELOGRAM,  RING,  TRIANGLE)
  505.            share a common normal finding routine.   If one of them should
  506.            suddenly need a different routine, just created it, and change
  507.            the object_data pointer for that object.
  508.            
  509.            Patterns are dealt with in the same  manner as objects.  There
  510.            are currently two types of  pattern  primitives (RECTANGLE and
  511.            CIRCLE). There is a structure (like the object_data structure)
  512.            for patterns.  This  structure  currently  contains  only  one
  513.            entry: a pointer to a collision function.  Future capabilities
  514.            may be added later, along with more primitive types.
  515.            
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.         QRT Ray Tracer               Page 8           Technical Reference
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.